package com.fingard.dsp.bank.directConfig;


import com.fingard.FGBiz;
import com.fingard.constant.Format;
import com.fingard.db.ConnSet;
import com.fingard.dsp.DSPSet;
import com.fingard.dsp.XmlHander;
import com.fingard.dsp.bankset.BankFront;
import com.fingard.io.FileHelper;
import com.fingard.text.StringHelper;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlReadMode;
import com.fingard.xml.XmlTextReader;

import java.io.File;
import java.util.*;

public class BankConfig {

    protected XmlTextReader cfgXmlReader;

    public BankConfig() {
        init();
    }

    public BankConfig(String p_filePath) {
        init();
        File tmpFile = new File(p_filePath);
        if (tmpFile.exists()) {
            String strXml = FileHelper.readToString(tmpFile, "utf-8");
            fromXmlStr(strXml);

        } else if (FGBiz.dspCenter.dspSet.useDBConn) {
            String strXml = "";
            String[] tmppaths = p_filePath.split(File.separator.equals("\\") ? "\\\\" : "/");
            try {
                strXml = XmlHander.dbtoxml(tmppaths[tmppaths.length - 2] + "config.xml", FGBiz.dspCenter.dspSet.dbConnectionSet.getConnection(), "config");
            } catch (Exception e) {
                //e.printStackTrace();
                FGBiz.limitMsg.exception("BankConfig", e, p_filePath);
            }
            fromXmlStr(strXml);
        }
    }

    protected void init() {
        hashKeyValue = new HashMap<String, HashMap<String, HashMap<String, String>>>();
        mapSimpleText = new HashMap<String, String>();
        mapConnSet = new HashMap<String, ConnSet>();
        mapForValues = new HashMap<String, HashMap<String, String>>();
        mapNotifySet = new HashMap<String, NotifySet>();
        mapFileSaveSet = new HashMap<String, FileSaveSet>();
        mapFtpSet = new HashMap<String, FtpSet>();
//        abstrPrefix = new HashMap<String, String>();
    }

    public void fromXmlStr(String pStrXml) {
        StringBuilder sbXml = new StringBuilder();
        sbXml.append(pStrXml);
        cfgXmlReader = new XmlTextReader(sbXml);
    }

    protected HashMap<String, String> mapSimpleText;
    protected HashMap<String, ConnSet> mapConnSet;

    /**
     * 对账码前缀
     */
//    protected HashMap<String,String> abstrPrefix;

    /**
     * 通知设置
     */
    protected HashMap<String, NotifySet> mapNotifySet;

    /**
     * 文件保存设置
     */
    protected HashMap<String, FileSaveSet> mapFileSaveSet;

    /**
     * ftp回单文件保存设置
     */
    protected HashMap<String, FtpSet> mapFtpSet;

    /**
     * 是否同城票交（跨行同城非加急时）
     */
    public boolean getLocalClearings() {
        return getValueAsBool("localClearings");
    }

    /**
     * 获取配置值返回boolean，
     * 示例：<a>true</a>返回true
     */
    public boolean getValueAsBool(String p_name) {
        if (cfgXmlReader == null) {
            return false;
        }
        try {
            String tmpValue;
            if (mapSimpleText.containsKey(p_name)) {
                tmpValue = mapSimpleText.get(p_name);
            } else {
                synchronized (mapSimpleText) {
                    cfgXmlReader.resetReadMode(XmlReadMode.SimpleInnerText);
                    tmpValue = cfgXmlReader.getSimpleText(p_name);
                    mapSimpleText.put(p_name, tmpValue);
                }
            }

            if (!StringHelper.isNullOrEmpty(tmpValue) && tmpValue.equalsIgnoreCase("true")) {
                return true;
            }
        } catch (Exception e) {
            //e.printStackTrace();
            FGBiz.limitMsg.exception("BankConfig", e, p_name);
        }
        return false;
    }

    public float getValueAsFloat(String p_name) {
        try {
            String v = getValueAsString(p_name);
            if (StringHelper.hasAnyChar(v)) {
                return Float.parseFloat(v);
            }
        } catch (Exception e) {
            //e.printStackTrace();
            FGBiz.limitMsg.exception("BankConfig", e, p_name);
        }
        return 0;
    }

    /**
     * 获取文件路径，将替换{$DSPHOME}等变量
     */
    public String getValueAsFilePath(String p_name) {
        String path = getValueAsString(p_name);
        if (StringHelper.hasAnyChar(path)) {
            path = DSPSet.replaceFilePath(path);
        }
        return path;
    }

    /**
     * 获取配置值
     */
    public String getValueAsString(String p_name) {
        if (cfgXmlReader == null) {
            return "";
        }
        try {
            String tmpValue;
            if (mapSimpleText.containsKey(p_name)) {
                tmpValue = mapSimpleText.get(p_name);
            } else {
                synchronized (mapSimpleText) {
                    cfgXmlReader.resetReadMode(XmlReadMode.SimpleInnerText);
                    tmpValue = cfgXmlReader.getSimpleText(p_name);
                    mapSimpleText.put(p_name, tmpValue);
                }
            }
            if (!StringHelper.isNullOrEmpty(tmpValue)) {
                return tmpValue;
            }
        } catch (Exception e) {
            //e.printStackTrace();
            FGBiz.limitMsg.exception("BankConfig", e, p_name);
        }
        return "";
    }

    /**
     * 获取配置值-设置默认值
     */
    public String getValueAsString(String p_name, String p_default) {
        String tmpValue = this.getValueAsString(p_name);
        if (StringHelper.isNullOrEmpty(tmpValue)) {
            tmpValue = p_default;
        }
        return tmpValue;
    }

    /**
     * 获取配置值返回int，
     * 示例：<a>12</a>返回12
     */
    public int getValueAsInt(String p_name) {
        return this.getValueAsInt(p_name, -1);
    }

    public int getValueAsInt(String p_name, int pDefVal) {
        if (cfgXmlReader == null) {
            return pDefVal;
        }
        try {
            String tmpValue;
            if (mapSimpleText.containsKey(p_name)) {
                tmpValue = mapSimpleText.get(p_name);
            } else {
                synchronized (mapSimpleText) {
                    cfgXmlReader.resetReadMode(XmlReadMode.SimpleInnerText);
                    tmpValue = cfgXmlReader.getSimpleText(p_name);
                    mapSimpleText.put(p_name, tmpValue);
                }
            }
            if (!StringHelper.isNullOrEmpty(tmpValue)) {
                return Integer.parseInt(tmpValue);
            }
        } catch (Exception e) {
            //e.printStackTrace();
            FGBiz.limitMsg.exception("BankConfig", e, p_name);
        }
        return pDefVal;
    }

    /**
     * @param pNodeName 节点名
     * @param pDefVal   默认值
     * @param pFor      for属性
     */
    public int getValueAsInt(String pNodeName, int pDefVal, String pFor) {
        String retVal = getSetValue(pNodeName, pDefVal + "", pFor);
        return Integer.parseInt(retVal);
    }

    /**
     * 获取通用节点charset配置，
     * 示例：<charset>utf-8</charset>，返回utf-8
     *
     * @return innerText
     */
    public String getCharset(String p_default) {
        String charset = getValueAsString("charset");
        if (StringHelper.isNullOrEmpty(charset)) {
            return p_default;
        }
        return charset;
    }

    public String getAbstrPrefix() {
        if (cfgXmlReader == null) {
            return "";
        }
        String value = "";
        synchronized (mapSimpleText) {
            cfgXmlReader.resetReadMode(XmlReadMode.XElementReader);
            try {
                if (cfgXmlReader.read("/config/abstrFormat")) {
//              String key = cfgXmlReader.readedXElement.innerText;
                    value = cfgXmlReader.readedXElement.getAttrValue("prefix");
//              abstrPrefix.put(key,value);
                }
            } catch (Exception e) {
                //e.printStackTrace();
                FGBiz.limitMsg.exception("BankConfig", e);
            }

        }
//        if(abstrPrefix.containsKey(innerText)){
//            return abstrPrefix.get(innerText);
//        }else{
//            return "";
//        }
        return value;
    }

    protected HashMap<String, String> hashCharset = null;

    public String getCharset(String p_default, String p_for) {

        if (cfgXmlReader == null) {
            return p_default;
        }
        try {
            if (hashCharset == null) {
                synchronized (mapSimpleText) {
                    HashMap<String, String> tmpHash = new HashMap<String, String>();
                    cfgXmlReader.resetReadMode(XmlReadMode.XElementReader);
                    while (cfgXmlReader.read("/config/charset")) {
                        String keyFor = cfgXmlReader.readedXElement.getAttrValue("for");
                        if (StringHelper.isNullOrEmpty(keyFor)) {
                            keyFor = "";
                        }
                        tmpHash.put(keyFor, cfgXmlReader.readedXElement.innerText);
                    }
                    hashCharset = tmpHash;
                }
            }

        } catch (Exception e) {
            //e.printStackTrace();
            FGBiz.limitMsg.exception("BankConfig", e, p_default, p_for);
        }
        if (hashCharset != null && hashCharset.containsKey(p_for)) {
            String retValue = hashCharset.get(p_for);
            if (StringHelper.hasAnyChar(retValue)) {
                return retValue;
            }
        }
        return getCharset(p_default);
    }

    protected HashMap<String, HashMap<String, String>> mapForValues = null;

    /**
     * 按节点名和多个for属性取设置值，返回第一个有值的
     */
    public String getSetValue(String p_nodeName, String p_default, String[] p_fors) {
        for (int i = 0; i < p_fors.length; i++) {
            String retValue = getSetValue(p_nodeName, "", p_fors[i]);
            if (StringHelper.hasAnyChar(retValue)) {
                return retValue;
            }
        }
        return p_default;
    }

    /**
     * 按节点名和for属性取设置值
     */
    public String getSetValue(String p_nodeName, String p_default, String p_for) {

        if (cfgXmlReader == null) {
            return p_default;
        }
        try {
            if (!mapForValues.containsKey(p_nodeName)) {
                synchronized (mapSimpleText) {
                    HashMap<String, String> tmpHash = new HashMap<String, String>();
                    cfgXmlReader.resetReadMode(XmlReadMode.XElementReader);
                    while (cfgXmlReader.read("/config/" + p_nodeName)) {
                        String keyFor = cfgXmlReader.readedXElement.getAttrValue("for");
                        if (StringHelper.isNullOrEmpty(keyFor)) {
                            keyFor = "";
                        }
                        tmpHash.put(keyFor, cfgXmlReader.readedXElement.innerText);
                    }
                    mapForValues.put(p_nodeName, tmpHash);
                }
            }

        } catch (Exception e) {
            //e.printStackTrace();
            FGBiz.limitMsg.exception("BankConfig", e, p_nodeName, p_default, p_for);
        }
        String retValue = p_default;
        HashMap<String, String> theMap = mapForValues.get(p_nodeName);
        if (theMap != null && theMap.containsKey(p_for)) {
            retValue = theMap.get(p_for);
        } else if (theMap != null && theMap.containsKey("*")) {
            retValue = theMap.get("*");
        }
        if (StringHelper.hasAnyChar(retValue)) {
            return retValue;
        }
        return p_default;
    }


    /**
     * 获取数据库连接配置
     */
    public ConnSet getConnSet(String p_nodename) throws Exception {
        if (cfgXmlReader == null) {
            return null;
        }
        if (mapConnSet.containsKey(p_nodename)) {
            return mapConnSet.get(p_nodename);
        }
        synchronized (mapSimpleText) {
            cfgXmlReader.resetReadMode(XmlReadMode.XElementReader);
            if (cfgXmlReader.read("/config/" + p_nodename)) {
                ConnSet tmpConnSet = new ConnSet();
                tmpConnSet.fromXElement(cfgXmlReader.readedXElement);
                mapConnSet.put(p_nodename, tmpConnSet);
                return tmpConnSet;
            }
        }
        return null;
    }

    /**
     * 获取NotifySet
     */
    public NotifySet getNotifySet(String p_for) throws Exception {
        if (cfgXmlReader == null) {
            return null;
        }

        if (mapNotifySet.size() <= 0) {
            synchronized (mapSimpleText) {
                cfgXmlReader.resetReadMode(XmlReadMode.XElementReader);
                if (cfgXmlReader.read("/config/notifySet")) {
                    NotifySet tmpSet = new NotifySet();
                    tmpSet.fromXElement(cfgXmlReader.readedXElement);
                    String tmpFor = cfgXmlReader.readedXElement.getAttrValue("for");
                    if (tmpFor == null) {
                        tmpFor = "";
                    }
                    mapNotifySet.put(tmpFor, tmpSet);
                    return tmpSet;
                }
            }
        }
        if (mapNotifySet.containsKey(p_for)) {
            return mapNotifySet.get(p_for);
        } else if (mapNotifySet.containsKey("*")) {
            return mapNotifySet.get("*");
        }
        return null;
    }

    /**
     * 获取FileSaveSet
     */
    public FileSaveSet getFileSaveSet(String p_for) throws Exception {
        if (cfgXmlReader == null) {
            return null;
        }

        if (mapFileSaveSet.size() <= 0) {
            synchronized (mapSimpleText) {
                cfgXmlReader.resetReadMode(XmlReadMode.XElementReader);
                while (cfgXmlReader.read("/config/fileSaveSet")) {
                    FileSaveSet tmpSet = new FileSaveSet();
                    tmpSet.fromXElement(cfgXmlReader.readedXElement);
                    String tmpFor = cfgXmlReader.readedXElement.getAttrValue("for");
                    if (tmpFor == null) {
                        tmpFor = "";
                    }
                    mapFileSaveSet.put(tmpFor, tmpSet);
                    //return tmpSet;
                }
            }
        }
        if (mapFileSaveSet.containsKey(p_for)) {
            return mapFileSaveSet.get(p_for);
        } else if (mapFileSaveSet.containsKey("*")) {
            return mapFileSaveSet.get("*");
        }
        return null;
    }


    private HashMap<String, ReceiptSet> mapReceiptSet = null;

    /**
     * 根据账号获取回单设置ReceiptSet，如果在receipt.xml中获取不到，则通过BankFront获取
     */
    public synchronized ReceiptSet getReceiptSetByAct(String pAct, BankFront pBankFront) throws Exception {
        if (mapReceiptSet == null) {
            HashMap<String, ReceiptSet> tmpMap = new HashMap<String, ReceiptSet>();
            if (cfgXmlReader != null) {
                cfgXmlReader.resetReadMode(XmlReadMode.XElementReader);
                while (cfgXmlReader.read("/config/receiptSet")) {
                    ReceiptSet tmpSet = new ReceiptSet();
                    tmpSet.fromXElement(cfgXmlReader.readedXElement);
                    if (StringHelper.hasAnyChar(tmpSet.act)) {
                        String[] actSp = tmpSet.act.split(",");
                        for (String eachAct : actSp) {
                            if (StringHelper.hasAnyChar(eachAct)) {
                                tmpMap.put(eachAct.trim(), tmpSet);
                            }
                        }
                    }
                }
            }
            mapReceiptSet = tmpMap;
        }
        if (mapReceiptSet.containsKey(pAct)) {
            return mapReceiptSet.get(pAct);
        } else {
            ReceiptSet receiptSet = new ReceiptSet();
            receiptSet.act = pAct;
            receiptSet.receiptDownloadType = pBankFront.getStrValueByFor("receiptDownloadType", "");
            receiptSet.bankReceiptMainDir = pBankFront.bankReceiptMainDir;
            receiptSet.ftpSet = pBankFront.getFtpSet("receipt");

            synchronized (mapReceiptSet) {
                if (!mapReceiptSet.containsKey(pAct)) {
                    mapReceiptSet.put(pAct, receiptSet);
                }
            }
            return receiptSet;
        }
    }

    /**
     * 模糊匹配
     *
     * @throws Exception
     */
    public String getMapIncludeValue(String p_nodename, String pMatchValue) throws Exception {
        HashMap<String, HashMap<String, String>> tmpHash = this.getHashMap(p_nodename, new String[]{"key"}, new String[]{"value"});
        if (tmpHash == null) {
            return "";
        } else {
            Iterator<String> iter = tmpHash.keySet().iterator();
            while (iter.hasNext()) {
                String eachKey = iter.next();
                if (pMatchValue.contains(eachKey)) {
                    HashMap<String, String> trgMap = tmpHash.get(eachKey);
                    if (trgMap.containsKey("value")) {
                        return trgMap.get("value");
                    }
                }
            }
        }
        return "";
    }

    protected HashMap<String, HashMap<String, HashMap<String, String>>> hashKeyValue = null;

    public HashMap<String, HashMap<String, String>> readHashMap(String p_nodename, String[] p_keyNames, String... p_valueNames) throws Exception {
        return this.getHashMap(p_nodename, p_keyNames, p_valueNames);
    }

    protected HashMap<String, HashMap<String, String>> getHashMap(String p_nodename, String[] p_keyNames, String... p_valueNames) throws Exception {
        if (cfgXmlReader == null) {
            return null;
        }
        String tmpNodeKey = p_nodename + "-" + StringHelper.join("-", p_keyNames) + "-" + StringHelper.join("-", p_valueNames);
        if (!hashKeyValue.containsKey(tmpNodeKey)) {
            synchronized (mapSimpleText) {
                HashMap<String, HashMap<String, String>> tmpHashKV = new HashMap<String, HashMap<String, String>>();
                cfgXmlReader.resetReadMode(XmlReadMode.XElementReader);
                while (cfgXmlReader.read("/config/" + p_nodename + "/item")) {
                    String[] tmpArrKeys = new String[p_keyNames.length];
                    for (int ik = 0; ik < p_keyNames.length; ik++) {
                        if (cfgXmlReader.readedXElement.hashMapAttributes.containsKey(p_keyNames[ik])) {
                            tmpArrKeys[ik] = cfgXmlReader.readedXElement.hashMapAttributes.get(p_keyNames[ik]);
                        } else {
                            tmpArrKeys[ik] = "";
                        }
                    }
                    String tmpKeyAdd = StringHelper.join("-", tmpArrKeys);
                    HashMap<String, String> tmpPairs = new HashMap<String, String>();

                    if (p_valueNames == null || p_valueNames.length == 0) {
                        Iterator<String> iter = cfgXmlReader.readedXElement.hashMapAttributes.keySet().iterator();
                        while (iter.hasNext()) {
                            String eachKey = iter.next();
                            if (!tmpPairs.containsKey(eachKey)) {
                                tmpPairs.put(eachKey, cfgXmlReader.readedXElement.hashMapAttributes.get(eachKey));
                            }
                        }
                    } else {
                        for (int i = 0; i < p_valueNames.length; i++) {
                            if (!tmpPairs.containsKey(p_valueNames[i])) {
                                if (cfgXmlReader.readedXElement.hashMapAttributes.containsKey(p_valueNames[i])) {
                                    tmpPairs.put(p_valueNames[i], cfgXmlReader.readedXElement.hashMapAttributes.get(p_valueNames[i]));
                                } else {
                                    tmpPairs.put(p_valueNames[i], "");
                                }
                            }
                        }
                    }
                    if (!tmpHashKV.containsKey(tmpKeyAdd)) {
                        tmpHashKV.put(tmpKeyAdd, tmpPairs);
                    }
                }
                hashKeyValue.put(tmpNodeKey, tmpHashKV);
            }
        }
        return hashKeyValue.get(tmpNodeKey);
    }

    //获取节点所有的子数据并封装到List中
    public List<HashMap<String, String>> getListHashMap(String p_nodename, String[] p_keyNames, String... p_valueNames) throws Exception {
        HashMap<String, HashMap<String, String>> tmpHash = this.getHashMap(p_nodename, p_keyNames, p_valueNames);
        List<HashMap<String, String>> resultList = new ArrayList<HashMap<String, String>>();
        if (tmpHash != null) {
            Iterator<String> iter = tmpHash.keySet().iterator();
            while (iter.hasNext()) {
                String eachKey = iter.next();
                HashMap<String, String> trgMap = tmpHash.get(eachKey);
                if (trgMap != null && trgMap.size() > 0) {
                    resultList.add(trgMap);
                }
            }
        }
        return resultList;
    }


    /**
     * Modified by cruise on 20171017 days
     *
     * @param p_nodename  BankCodeMapping
     * @param p_srcNames  new String[]{"ATSBankCode","ATSAreaName"}
     * @param p_trgNames  new String[]{"value"}
     * @param p_srcValues new String[]{PayBankCode,PayAreaName or  RecBankCode,RecAreaName}
     * @return bankCode
     * @throws Exception communication exception
     */
    public HashMap<String, String> getMapAdvanceValues(String p_nodename, String[] p_srcNames, String[] p_trgNames, String[] p_srcValues) throws Exception {
        return getMapAdvanceValues(p_nodename, p_srcNames, p_trgNames, p_srcValues, true);
    }

    public HashMap<String, String> getMapAdvanceValues(String p_nodename, String[] p_srcNames, String[] p_trgNames, String[] p_srcValues, boolean enableWildcard) throws Exception {
        if (cfgXmlReader == null) {
            return null;
        }
        HashMap<String, HashMap<String, String>> tmpHash = this.getHashMap(p_nodename, p_srcNames, p_trgNames);
        if (tmpHash == null) {
            return null;
        }
        String tmpKeyValues = StringHelper.join("-", p_srcValues);
        if (tmpHash.containsKey(tmpKeyValues)) {
            return (HashMap<String, String>) tmpHash.get(tmpKeyValues).clone();
        } else if (enableWildcard) {
            for (int i = 0; i < p_srcValues.length; i++) {
                int step = i;
                for (int j = 0; j < p_srcValues.length; j++) {
                    String[] mValues = new String[p_srcValues.length];

                    for (int k = 0; k <= step; k++) {
                        mValues[k] = p_srcValues[k];
                    }

                    for (int n = step + 1; n < p_srcValues.length; n++) {
                        mValues[n] = "*";
                    }
                    if (p_srcValues.length == 1) {
                        mValues[0] = "*";
                    }

                    String eachKeyValues = StringHelper.join("-", mValues);
                    if (tmpHash.containsKey(eachKeyValues)) {
                        return (HashMap<String, String>) tmpHash.get(eachKeyValues).clone();
                    }
                }
            }
        }
        return null;
    }

    public String getMapAdvanceValuesExtra(String p_nodename, String[] p_srcNames, String p_trgName, String[] p_srcValues) throws Exception {
        HashMap<String, String> tmpHash = getMapAdvanceValuesExtra(p_nodename, p_srcNames, new String[]{p_trgName}, p_srcValues, true);
        if (tmpHash != null && tmpHash.containsKey(p_trgName)) {
            return tmpHash.get(p_trgName);
        }
        return "";
    }

    public HashMap<String, String> getMapAdvanceContainsValues(String p_nodename, String[] p_srcNames, String[] p_trgNames, String[] p_srcValues) throws Exception {
        if (cfgXmlReader == null) {
            return null;
        }
        HashMap<String, HashMap<String, String>> tmpHash = this.getHashMap(p_nodename, p_srcNames, p_trgNames);
        String tmpKeyValues = StringHelper.join("-", p_srcValues);
        boolean isContains = false;
        String keyVaule = "";

        for (Map.Entry<String, HashMap<String, String>> entry : tmpHash.entrySet()) {
            if (tmpKeyValues.contains(entry.getKey())) {
                isContains = true;
                keyVaule = entry.getKey();
                break;
            }
        }

        if (isContains) {
            return (HashMap<String, String>) tmpHash.get(keyVaule).clone();
        } else {
            for (int i = 0; i < p_srcValues.length; i++) {
                int step = i;
                for (int j = 0; j < p_srcValues.length; j++) {
                    String[] mValues = new String[p_srcValues.length];

                    for (int k = 0; k <= step; k++) {
                        mValues[k] = p_srcValues[k];
                    }

                    for (int n = step + 1; n < p_srcValues.length; n++) {
                        mValues[n] = "*";
                    }

                    if (p_srcValues.length == 1) {
                        mValues[0] = "*";
                    }

                    String eachKeyValues = StringHelper.join("-", mValues);
                    if (tmpHash.containsKey(eachKeyValues)) {
                        return (HashMap<String, String>) tmpHash.get(eachKeyValues).clone();
                    }
                }
            }
        }
        return null;
    }

    public HashMap<String, String> getMapAdvanceValuesExtra(String p_nodename, String[] p_srcNames, String[] p_trgNames, String[] p_srcValues) throws Exception {
        return getMapAdvanceValuesExtra(p_nodename, p_srcNames, p_trgNames, p_srcValues, true);
    }

    public HashMap<String, String> getMapAdvanceValuesExtra(String p_nodename, String[] p_srcNames, String[] p_trgNames, String[] p_srcValues, boolean enableWildcard) throws Exception {
        if (cfgXmlReader == null) {
            return null;
        }
        HashMap<String, HashMap<String, String>> tmpHash = this.getHashMap(p_nodename, p_srcNames, p_trgNames);
        if (tmpHash == null) {
            return null;
        }
        String tmpKeyValues = StringHelper.join("-", p_srcValues);
        if (tmpHash.containsKey(tmpKeyValues)) {
            return (HashMap<String, String>) tmpHash.get(tmpKeyValues).clone();
        } else if (enableWildcard) {
            if (StringHelper.hasAnyChar(tmpKeyValues)) {
                //为*的值可在任意一位或任意几位
                Map<String, ArrayList<String[]>> tmpAllKey = new HashMap<String, ArrayList<String[]>>();
                if ("*".equals(p_srcValues[0])) {
                    ArrayList<String[]> tmpKey = new ArrayList<String[]>();
                    tmpKey.add(p_srcValues);
                    tmpAllKey.put("1", tmpKey);
                } else {
                    String[] tmp1 = p_srcValues;
                    tmp1[0] = "*";
                    String tmpKeyValue = StringHelper.join("-", tmp1);
                    if (tmpHash.containsKey(tmpKeyValue)) {
                        return (HashMap<String, String>) tmpHash.get(tmpKeyValue).clone();
                    }
                    ArrayList<String[]> tmpKey = new ArrayList<String[]>();
                    tmpKey.add(p_srcValues);
                    tmpKey.add(tmp1);
                    tmpAllKey.put("1", tmpKey);
                }
                for (int i = 1; i < p_srcValues.length; i++) {
                    //每一位的值均有两种可能，要么为自身的值要么为*，当为*时，可直接进行下次处理
                    if (!"*".equals(p_srcValues[i])) {
                        ArrayList<String[]> tmpKey = tmpAllKey.get(String.valueOf(i));
                        for (String[] tmpStrs : tmpKey) {
                            String[] tmpStr = tmpStrs;
                            tmpStr[i] = "*";
                            String tmpKeyValue = StringHelper.join("-", tmpStr);
                            if (tmpHash.containsKey(tmpKeyValue)) {
                                return (HashMap<String, String>) tmpHash.get(tmpKeyValue).clone();
                            }
                            ArrayList<String[]> tmpNewKey = new ArrayList<String[]>();
                            tmpNewKey.add(tmpStrs);
                            tmpNewKey.add(tmpStr);
                            tmpAllKey.put(String.valueOf(i + 1), tmpNewKey);
                        }
                    }
                }
            }
        }
        return null;
    }


    /**
     * @param p_nodename:配置节点名
     * @param p_srcName:配置的item源节点属性名
     * @param p_trgName:配置的item目的节点属性名
     * @param p_srcXE:源值XElement
     * @param p_defSrcValue:默认原值，当没有配置mapColumn时采用该值进行映射
     */
    public String getMapValueBySrcXE(String p_nodename, String p_srcName, String p_trgName, XElement p_srcXE, String p_defSrcValue) throws Exception {
        if (cfgXmlReader == null) {
            return "";
        }
        String mapColumn = "";
        synchronized (mapSimpleText) {
            cfgXmlReader.resetReadMode(XmlReadMode.XElementReader);
            if (cfgXmlReader.read("/config/" + p_nodename)) {
                XElement cfgNode = cfgXmlReader.readedXElement;
                mapColumn = cfgNode.getAttrValue("mapColumn");
            } else {
                return "";
            }
            cfgXmlReader.backToTop();
        }
        String retValue = "";
        if (StringHelper.hasAnyChar(mapColumn)) {
            String[] mColumns = mapColumn.split(",");
            for (int i = 0; i < mColumns.length; i++) {
                String eachSrcValue = p_srcXE.getSingleText(mColumns[i].trim());
                if (StringHelper.hasAnyChar(eachSrcValue)) {
                    retValue = getMapAdvanceValue(p_nodename, p_srcName, p_trgName, eachSrcValue, false);
                    if (StringHelper.hasAnyChar(retValue)) {
                        return retValue;
                    }
                }
            }
        }
        if (StringHelper.isNullOrEmpty(retValue)) {
            retValue = getMapAdvanceValue(p_nodename, p_srcName, p_trgName, p_defSrcValue, true);
        }
        return retValue;
    }

    public String getMapAdvanceValue(String p_nodename, String p_srcName, String p_trgName, String p_srcValue) throws Exception {
        return getMapAdvanceValue(p_nodename, p_srcName, p_trgName, p_srcValue, true);
    }

    public String getMapAdvanceValue(String p_nodename, String p_srcName, String p_trgName, String p_srcValue, boolean enableWildcard) throws Exception {
        HashMap<String, String> tmpHash = getMapAdvanceValues(p_nodename, new String[]{p_srcName}, new String[]{p_trgName}, new String[]{p_srcValue}, enableWildcard);
        if (tmpHash != null && tmpHash.containsKey(p_trgName)) {
            return tmpHash.get(p_trgName);
        }
        return "";
    }

    //通过srcName找trgName
    public HashMap<String, String> getMapAllValuesByKey(String p_nodename, String p_srcValue) throws Exception {
        return getMapAdvanceValues(p_nodename, new String[]{"key"}, new String[]{"value"}, new String[]{p_srcValue});
    }

    public String getMapValueByKey(String p_nodename, String p_keyValue) throws Exception {
        HashMap<String, String> tmpHash = getMapAdvanceValues(p_nodename, new String[]{"key"}, new String[]{"value"}, new String[]{p_keyValue});
        if (tmpHash != null && tmpHash.containsKey("value")) {
            return tmpHash.get("value");
        }
        return "";
    }

    public String[] getMapValue2ByKey(String p_nodename, String p_keyValue) throws Exception {
        String[] tmpHash = new String[2];
        HashMap<String, String> tmpHash1 = getMapAdvanceValues(p_nodename, new String[]{"key"}, new String[]{"value1"}, new String[]{p_keyValue});
        HashMap<String, String> tmpHash2 = getMapAdvanceValues(p_nodename, new String[]{"key"}, new String[]{"value2"}, new String[]{p_keyValue});
        if (tmpHash1 != null && tmpHash1.containsKey("value1") && tmpHash2 != null && tmpHash2.containsKey("value2")) {
            tmpHash[0] = tmpHash1.get("value1");
            tmpHash[1] = tmpHash2.get("value2");
            return tmpHash;
        }
        return tmpHash;
    }

    public String getMapDesByKey(String p_nodename, String p_keyValue) throws Exception {
        HashMap<String, String> tmpHash = getMapAdvanceValues(p_nodename, new String[]{"key"}, new String[]{"des"}, new String[]{p_keyValue});
        if (tmpHash != null && tmpHash.containsKey("des")) {
            return tmpHash.get("des");
        }
        return "";
    }

    public String getMapValueByContainsKey(String p_nodename, String p_keyValue) throws Exception {
        HashMap<String, String> tmpHash = getMapAdvanceContainsValues(p_nodename, new String[]{"key"}, new String[]{"value"}, new String[]{p_keyValue});
        if (tmpHash != null && tmpHash.containsKey("value")) {
            return tmpHash.get("value");
        }
        return "";
    }

    public String getMapKeyByValue(String p_nodename, String p_value) throws Exception {
        HashMap<String, String> tmpHash = getMapAdvanceValues(p_nodename, new String[]{"value"}, new String[]{"key"}, new String[]{p_value});
        if (tmpHash != null && tmpHash.containsKey("key")) {
            return tmpHash.get("key");
        }
        return "";
    }

    protected HashMap<String, NodeAnalysisSet> hashNodeAnalySet = null;

    public NodeAnalysisSet getNodeAnalysisSet(String... p_values) {
        loadNodeAnalysisSet();
        if (hashNodeAnalySet != null) {
            for (int i = 0; i < p_values.length; i++) {
                if (hashNodeAnalySet.containsKey(p_values[i])) {
                    return hashNodeAnalySet.get(p_values[i]);
                }
            }
        }
        return null;
    }

    protected void loadNodeAnalysisSet() {
        if (cfgXmlReader == null) {
            return;
        }
        try {
            if (hashNodeAnalySet == null) {
                synchronized (mapSimpleText) {
                    HashMap<String, NodeAnalysisSet> tmpHash = new HashMap<String, NodeAnalysisSet>();
                    cfgXmlReader.resetReadMode(XmlReadMode.XElementReader);
                    while (cfgXmlReader.read("/config/nodeAnalysis")) {

                        NodeAnalysisSet nodeSet = new NodeAnalysisSet();
                        nodeSet.fromXElement(cfgXmlReader.readedXElement);
                        tmpHash.put(nodeSet.setFor, nodeSet);

                    }
                    hashNodeAnalySet = tmpHash;
                }
            }
        } catch (Exception e) {
            //e.printStackTrace();
            FGBiz.limitMsg.exception("BankConfig", e);
        }
    }

    protected HashMap<String, EBankSet> hashEBankSet = null;

    public EBankSet getEBankSet(String... p_values) {
        loadEBankSet();
        if (hashEBankSet != null) {
            for (int i = 0; i < p_values.length; i++) {
                if (hashEBankSet.containsKey(p_values[i])) {
                    return hashEBankSet.get(p_values[i]);
                }
            }
        }
        return null;
    }

    protected void loadEBankSet() {
        if (cfgXmlReader == null) {
            return;
        }
        try {
            if (hashEBankSet == null) {
                synchronized (mapSimpleText) {
                    HashMap<String, EBankSet> tmpHash = new HashMap<String, EBankSet>();
                    cfgXmlReader.resetReadMode(XmlReadMode.XElementReader);
                    while (cfgXmlReader.read("/config/ebank")) {
                        EBankSet nodeSet = new EBankSet();
                        nodeSet.fromXElement(cfgXmlReader.readedXElement);
                        tmpHash.put(nodeSet.setFor, nodeSet);
                    }
                    hashEBankSet = tmpHash;
                }
            }
        } catch (Exception e) {
            //e.printStackTrace();
            FGBiz.limitMsg.exception("BankConfig", e);
        }
    }


    protected HashMap<String, ActSetItem> hashActSet = null;

    /**
     * 根据商户号找配置
     */
    public ActSetItem getActSetItemByMerId(String p_merId, String p_for) {
        String matchKey = p_merId + "-" + p_for + "-merId";
        ActSetItem retActItem = getActSetItemByKey(matchKey);
        if (retActItem != null) {
            return retActItem;
        } else {
            matchKey = p_merId + "-*-merId";
            return getActSetItemByKey(matchKey);
        }
    }

    /**
     * 根据公众号找配置
     */
    public ActSetItem getActSetItemByAppId(String p_appId, String p_for) {
        String matchKey = p_appId + "-" + p_for + "-appId";
        ActSetItem retActItem = getActSetItemByKey(matchKey);
        if (retActItem != null) {
            return retActItem;
        } else {
            matchKey = p_appId + "-*-appId";
            return getActSetItemByKey(matchKey);
        }
    }

    /**
     * 根据ATS账号找配置
     */
    public ActSetItem getActSetItem(String p_actATS, String p_for) {
        String matchKey = p_actATS + "-" + p_for;
        ActSetItem retActItem = getActSetItemByKey(matchKey);
        if (retActItem != null) {
            return retActItem;
        } else {
            matchKey = p_actATS + "-*";
            //cfgXmlReader.sbLog.append(Format.DateTimeSSSFormat.format(new Date()) + "\t当前商户配置待匹配KEY匹配失败，开始使用默认商户配置KEY进行重新匹配:\r\n");
            //cfgXmlReader.sbLog.append(Format.DateTimeSSSFormat.format(new Date()) + "\t"+matchKey+"\r\n\r\n");
            return getActSetItemByKey(matchKey);
        }
    }

    public ActSetItem getActSetItemByAny(String p_actATS, String p_merId, String p_appId, String p_for) {
        if (StringHelper.hasAnyChar(p_appId)) {
            p_actATS = p_actATS + "-" + p_appId;
        }
        ActSetItem retItem = getActSetItem(p_actATS, p_for);
        if (retItem != null) {
            return retItem;
        }
        retItem = getActSetItemByMerId(p_merId, p_for);
        if (retItem != null) {
            return retItem;
        }
        retItem = getActSetItemByAppId(p_appId, p_for);
        if (retItem != null) {
            return retItem;
        }
        return null;
    }

    protected ActSetItem getActSetItemByKey(String p_key) {
        loadActSetItem();

        /*
        cfgXmlReader.sbLog.append(Format.DateTimeSSSFormat.format(new Date()) + "\t当前商户配置待匹配KEY   (命名规则：actATS-for,其中actATS等节点取自config.xml商户配置item中的actATS和for属性值)");
        cfgXmlReader.sbLog.append("\r\n" + Format.DateTimeSSSFormat.format(new Date()) + "\t"+p_key+"\r\n\r\n");
        cfgXmlReader.sbLog.append(Format.DateTimeSSSFormat.format(new Date()) + "\t当前config.xml中存在的商户配置KEY列表:\r\n");

        if(hashActSet != null && hashActSet.size() > 0) {
            Iterator<String> iterator = hashActSet.keySet().iterator();
            while (iterator.hasNext()) {
                String matchKey = iterator.next();
                if(StringHelper.hasAnyChar(p_key) && p_key.split("-") != null) {
                    if (matchKey.contains(p_key.split("-")[0])) {
                        cfgXmlReader.sbLog.append(Format.DateTimeSSSFormat.format(new Date()) + "\t"+matchKey+"\r\n");
                    }
                }
            }
        }
        cfgXmlReader.sbLog.append("\r\n");
        */

        if (hashActSet != null && hashActSet.containsKey(p_key)) {
            //cfgXmlReader.sbLog.append(Format.DateTimeSSSFormat.format(new Date()) + "\t当前商户配置待匹配KEY匹配成功!\r\n\r\n");
            return hashActSet.get(p_key);
        } else {
            //cfgXmlReader.sbLog.append(Format.DateTimeSSSFormat.format(new Date()) + "\t当前商户配置待匹配KEY匹配失败!\r\n\r\n");
        }
        return null;
    }

    protected void loadActSetItem() {
        if (cfgXmlReader == null) {
            return;
        }
        try {
            if (hashActSet == null) {
                synchronized (mapSimpleText) {
                    HashMap<String, ActSetItem> tmpHash = new HashMap<String, ActSetItem>();
                    cfgXmlReader.resetReadMode(XmlReadMode.XElementReader);
                    while (cfgXmlReader.read("/config/actSet/item")) {

                        ActSetItem item = new ActSetItem();
                        item.fromXElement(cfgXmlReader.readedXElement);

                        String tmpKey = "";
                        if (StringHelper.hasAnyChar(item.actATS)) {
                            String actATS = item.actATS;
                            if (actATS.contains(",")) {
                                String[] actATSArray = actATS.split(",");
                                for (String tmpActATS : actATSArray) {
                                    if (StringHelper.isNullOrEmpty(tmpActATS)) {
                                        continue;
                                    }
                                    tmpKey = tmpActATS + "-" + item.forTrg;
                                    if (!tmpHash.containsKey(tmpKey)) {
                                        tmpHash.put(tmpKey, item);
                                    }
                                }
                            } else {
                                tmpKey = item.actATS + "-" + item.forTrg;
                                if (!tmpHash.containsKey(tmpKey)) {
                                    tmpHash.put(tmpKey, item);
                                }
                            }
                        }
                        if (StringHelper.hasAnyChar(item.merchantId)) {
                            tmpKey = item.merchantId + "-" + item.forTrg + "-merId";
                            if (!tmpHash.containsKey(tmpKey)) {
                                tmpHash.put(tmpKey, item);
                            }
                        }
                        if (StringHelper.hasAnyChar(item.appId)) {
                            tmpKey = item.appId + "-" + item.forTrg + "-appId";
                            if (!tmpHash.containsKey(tmpKey)) {
                                tmpHash.put(tmpKey, item);
                            }
                        }
                    }
                    hashActSet = tmpHash;

                    //Iterator<String> iterator = tmpHash.keySet().iterator();
                    //while(iterator.hasNext()) {
                    //	System.out.println(iterator.next());
                    //}
                }
            }
        } catch (Exception e) {
            //e.printStackTrace();
            FGBiz.limitMsg.exception("BankConfig", e);
        }
    }

    /**
     * 获取ReceiptFtpSet
     */
    public FtpSet getReceiptFtpSet(String p_for) throws Exception {
        if (cfgXmlReader == null) {
            return null;
        }

        if (mapFtpSet.size() <= 0) {
            synchronized (mapSimpleText) {
                cfgXmlReader.resetReadMode(XmlReadMode.XElementReader);
                while (cfgXmlReader.read("/config/receiptFtpSet")) {
                    FtpSet tmpSet = new FtpSet();
                    tmpSet.fromXElement(cfgXmlReader.readedXElement);
                    String tmpFor = cfgXmlReader.readedXElement.getAttrValue("for");
                    if (tmpFor == null) {
                        tmpFor = "";
                    }
                    mapFtpSet.put(tmpFor, tmpSet);
                    //return tmpSet;
                }
            }
        }
        if (mapFtpSet.containsKey(p_for)) {
            return mapFtpSet.get(p_for);
        } else if (mapFtpSet.containsKey("*")) {
            return mapFtpSet.get("*");
        }
        return null;
    }

    public Boolean hasNode(String p_nodename) {
        Boolean ret = false;
        try {
            if (cfgXmlReader == null) {
                return ret;
            }
            cfgXmlReader.resetReadMode(XmlReadMode.XElementReader);
            while (cfgXmlReader.read("/config/" + p_nodename)) {
                ret = true;
                break;
            }
        } catch (Exception e) {
            ret = false;
        } finally {
            return ret;
        }
    }
}
